/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.dev/license
 */

import {HighlighterGeneric} from 'shiki';

/**
 * Singleton instance of the Shiki highlighter used during API page generation.
 *
 * TODO: Consider removing this singleton pattern if we find a better alternative.
 */
let highlighter: HighlighterGeneric<any, any>;
export function setHighlighterInstance(instance: HighlighterGeneric<any, any>) {
  highlighter = instance;
}
export function getHighlighterInstance(): HighlighterGeneric<any, any> {
  if (!highlighter) {
    throw new Error(
      'Shiki highlighter has not been initialized. Make sure to call `setHighlighterInstance`.',
    );
  }
  return highlighter;
}

/**
 * This function is used to post-process the HTML generated by Shiki
 */
export function replaceKeywordFromShikiHtml(
  keyword: string,
  shikiHtml: string,
  replaceWith: string,
): string {
  return (
    shikiHtml
      // remove the leading space of the element after the keyword
      .replace(
        new RegExp(`(<[^>]*>(?:${keyword})<\\/\\w+><[^>]*>)(\\s)(\\w+<\\/\\w+>)`, 'g'),
        '$1$3',
      )
      // Shiki requires the keywords (eg. function,interface) for highlighting signatures
      // here we are replacing it
      .replace(new RegExp(`<[^>]*>(?:${keyword})<\\/\\w+>`, 'g'), replaceWith)
  );
}

export function insertParenthesesForDecoratorInShikiHtml(shikiHtml: string): string {
  // TODO: Look if we can use JSDom instead of regex

  return shikiHtml.replace(
    // This will match a structure like this:
    // @<span>decoratorName</span><span> {</span><span>...</span><span> }</span>
    // and insert a parenthese around the curly braces
    // @<span>decoratorName</span><span> ({</span><span>...</span><span> })</span>
    /(@\s*<[^>]*>.*?<\/\w+>\s*<[^>]*>)(\s*\{)(<\/\w+>.*<[^>]*>)(\s*\})(<\/\w+>)/gms,
    '$1({$3})$5',
  );
}
